<template>
    <div class="pdf-test">
      <h2>PDF 测试页面</h2>
      <div class="upload-container">
        <input type="file" @change="handlePdfUpload" accept="application/pdf" />
        <div class="preview" v-if="pdfPreviewUrl">
          <img :src="pdfPreviewUrl" alt="PDF预览" />
          <div class="download-buttons">
            <button class="download-btn" @click="downloadOriginal">
              <span class="download-icon">↓</span>下载原图
            </button>
            <button class="download-btn" @click="downloadCropped">
              <span class="download-icon">↓</span>下载裁剪图
            </button>
          </div>
        </div>
      </div>
      <router-link to="/" class="back-link">返回首页</router-link>
  
      <!-- 裁剪弹框 -->
      <div class="modal" v-if="showModal" @click.self="closeModal">
        <div class="modal-content">
          <h3>请选择封面区域</h3>
          <div class="page-selector" v-if="totalPages > 0">
            <span>选择页码：</span>
            <select v-model="currentPage" @change="handlePageChange">
              <option v-for="n in totalPages" :key="n" :value="n">
                第 {{ n }} 页
              </option>
            </select>
            <span class="total-pages">(共 {{ totalPages }} 页)</span>
          </div>
          <div class="zoom-controls">
            <button class="zoom-btn" @click="zoomIn">
              <span class="zoom-icon">+</span>放大
            </button>
            <button class="zoom-btn" @click="zoomOut">
              <span class="zoom-icon">-</span>缩小
            </button>
            <button class="zoom-btn" @click="resetCrop">
              <span class="zoom-icon">↺</span>重置
            </button>
          </div>
          <div class="crop-container" ref="cropContainer">
            <img :src="originalPdfUrl" ref="cropImage" @load="initCrop" />
          </div>
          <div class="size-buttons">
            <button 
              v-for="size in sizeOptions" 
              :key="size.scale"
              :class="['size-btn', { active: currentScale === size.scale }]"
              @click="changeSize(size.scale)"
            >
              {{ size.label }}
            </button>
          </div>
          <div class="crop-info" v-if="cropInfo">
            原图尺寸: {{ originalSize }}，
            截取尺寸: {{ cropInfo.currentSize }} <br>
            <!-- 添加压缩比例滑块 -->
            <div class="quality-control">
              <span>清晰度: {{ quality }}%</span>
              <input 
                type="range" 
                v-model="quality" 
                min="1" 
                max="100" 
                step="1" 
                class="quality-slider"
              >
            </div>
          </div>
          <div class="modal-buttons">
            <button @click="handleCrop" class="confirm-btn">确认</button>
            <button @click="closeModal" class="cancel-btn">取消</button>
          </div>
        </div>
      </div>
    </div>
  </template>
  
  <script setup>
  import { ref, nextTick } from 'vue'
  import * as PDFJS from 'pdfjs-dist/build/pdf'
  import Cropper from 'cropperjs'
  import 'cropperjs/dist/cropper.css'
  
  PDFJS.GlobalWorkerOptions.workerSrc = '/workers/pdf.worker.min.js'

  
  const pdfPreviewUrl = ref('')
  const originalPdfUrl = ref('')
  const showModal = ref(false)
  const cropImage = ref(null)
  const cropper = ref(null)
  const cropInfo = ref(null)
  const currentScale = ref(1)
  const originalSize = ref('')
  const quality = ref(50) // 默认压缩比例为60%
  const currentPage = ref(1)
  const totalPages = ref(0)
  const pdfDoc = ref(null)
  
  const sizeOptions = [
    { scale: 1, label: '1倍(56×70)', width: 56, height: 70 },
    { scale: 1.5, label: '1.5倍 (84×105)', width: 84, height: 105 },
    { scale: 2, label: '2倍 (112×140)', width: 112, height: 140 },
    { scale: 3, label: '3倍 (168×210)', width: 168, height: 210 },
    { scale: 4, label: '4倍 (224×280)', width: 224, height: 280 },
    { scale: 5, label: '5倍 (280×350)', width: 280, height: 350 },
    { scale: 6, label: '6倍 (336×420)', width: 336, height: 420 },
    { scale: 'fit', label: '适应', width: 56, height: 70 }
  ]
  
  const handlePdfUpload = async (event) => {
    const file = event.target.files[0]
    if (!file) return
  
    const fileReader = new FileReader()
    fileReader.onload = async function() {
      try {
        const typedarray = new Uint8Array(this.result)
        pdfDoc.value = await PDFJS.getDocument(typedarray).promise
        totalPages.value = pdfDoc.value.numPages
        currentPage.value = 1
        await renderPage()
        showCropModal()
      } catch (error) {
        console.error('PDF 加载失败:', error)
      }
    }
    fileReader.readAsArrayBuffer(file)
  }
  
  const renderPage = async () => {
    if (!pdfDoc.value) return
  
    try {
      const page = await pdfDoc.value.getPage(currentPage.value)
      const viewport = page.getViewport({ scale: 1.5 })
      const canvas = document.createElement('canvas')
      const context = canvas.getContext('2d')
  
      canvas.height = viewport.height
      canvas.width = viewport.width
  
      const renderContext = {
        canvasContext: context,
        viewport: viewport,
        enableWebGL: true
      }
  
      try {
        await page.render(renderContext).promise
        originalSize.value = `${canvas.width} × ${canvas.height}`
        originalPdfUrl.value = canvas.toDataURL('image/jpeg', 1.0)
  
        if (cropper.value) {
          cropper.value.destroy()
          cropper.value = null
        }
        await nextTick()
        initCrop()
      } catch (renderError) {
        console.error('渲染失败:', renderError)
      }
    } catch (error) {
      console.error('获取页面失败:', error)
    }
  }
  
  const handlePageChange = async () => {
    await renderPage()
  }
  
  const showCropModal = () => {
    currentScale.value = 1
    showModal.value = true
  }
  
  const closeModal = () => {
    showModal.value = false
    if (cropper.value) {
      cropper.value.destroy()
      cropper.value = null
    }
  }
  
  const fitSize = () => {
    if (!cropper.value) return
    
    const imageData = cropper.value.getImageData()
    
    // 使用图片的实际尺寸
    const imageWidth = imageData.naturalWidth
    const imageHeight = imageData.naturalHeight
    
    // 计算保持 56:70 比例的最大尺寸
    let width, height
    if (imageWidth / imageHeight > 56 / 70) {
      // 高度限制
      height = imageHeight
      width = (height * 56) / 70
    } else {
      // 宽度限制
      width = imageWidth
      height = (width * 70) / 56
    }
    
    // 获取容器数据以计算居中位置
    const containerData = cropper.value.getContainerData()
    const left = (containerData.width - width) / 2
    const top = (containerData.height - height) / 2
    
    // 设置裁剪框位置和大小
    cropper.value.setCropBoxData({
      left,
      top,
      width,
      height
    })
  
    // 立即更新裁剪信息
    updateCropInfo(width, height)
  }
  
  // 新增一个更新裁剪信息的函数
  const updateCropInfo = (width, height) => {
    cropInfo.value = {
      currentSize: `${Math.round(width)} × ${Math.round(height)}`,
      targetSize: currentScale.value === 'fit' ? '适应原图最大尺寸' : ''
    }
  }
  
  const changeSize = (scale) => {
    currentScale.value = scale
    if (scale === 'fit') {
      fitSize()
      return
    }
  
    const size = sizeOptions.find(s => s.scale === scale)
    if (cropper.value && size) {
      const cropBox = cropper.value.getCropBoxData()
      const centerX = cropBox.left + cropBox.width / 2
      const centerY = cropBox.top + cropBox.height / 2
      
      const newWidth = size.width
      const newHeight = size.height
      
      cropper.value.setCropBoxData({
        left: centerX - (newWidth / 2),
        top: centerY - (newHeight / 2),
        width: newWidth,
        height: newHeight
      })
  
      // 立即更新裁剪信息
      updateCropInfo(newWidth, newHeight)
    }
  }
  
  const zoomIn = () => {
    if (cropper.value) {
      cropper.value.zoom(0.1) // 放大 10%
    }
  }
  
  const zoomOut = () => {
    if (cropper.value) {
      cropper.value.zoom(-0.1) // 缩小 10%
    }
  }
  
  const resetCrop = () => {
    if (cropper.value) {
      // 重置缩放和位置
      cropper.value.reset()
      // 重置裁剪框到适应尺寸
      fitSize()
      // 重置当前比例为适应
      currentScale.value = 'fit'
    }
  }
  
  const initCrop = () => {
    if (cropper.value) {
      cropper.value.destroy()
    }
  
    const image = cropImage.value
    if (!image) return
  
    cropper.value = new Cropper(image, {
      aspectRatio: 56/70,
      viewMode: 2, // 修改为 viewMode: 2，限制裁剪框不超出图片
      dragMode: 'move',
      autoCropArea: 1,
      minContainerWidth: 400,
      minContainerHeight: 500,
      minCropBoxWidth: 56,
      minCropBoxHeight: 70,
      zoomable: true,
      zoomOnWheel: true,
      wheelZoomRatio: 0.1,
      ready() {
        // 初始化时使用适应尺寸
        fitSize()
        currentScale.value = 'fit'
      },
      crop(event) {
        // 更新裁剪信息
        updateCropInfo(event.detail.width, event.detail.height)
      }
    })
  }
  
  const handleCrop = () => {
    if (!cropper.value) return
  
    const size = sizeOptions.find(s => s.scale === currentScale.value)
    if (!size) return
  
    let width, height
    if (size.scale === 'fit') {
      const cropData = cropper.value.getData()
      width = Math.round(cropData.width)
      height = Math.round(cropData.height)
    } else {
      width = size.width
      height = size.height
    }
  
    const canvas = cropper.value.getCroppedCanvas({
      width: width,
      height: height,
      imageSmoothingQuality: 'high',
      imageSmoothingEnabled: true
    })
  
    // 使用设置的压缩比例
    pdfPreviewUrl.value = canvas.toDataURL('image/jpeg', quality.value / 100)
    closeModal()
  }
  
  // 下载辅助函数
  const downloadImage = (dataUrl, fileName) => {
    const link = document.createElement('a')
    link.href = dataUrl
    link.download = fileName
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
  }
  
  // 下载原图
  const downloadOriginal = () => {
    if (originalPdfUrl.value) {
      downloadImage(originalPdfUrl.value, 'original.jpg')
    }
  }
  
  // 修改下载裁剪图函数，使用当前压缩比例
  const downloadCropped = () => {
    if (pdfPreviewUrl.value) {
      // 从文件名中反映压缩比例
      downloadImage(pdfPreviewUrl.value, `cropped_q${quality.value}.jpg`)
    }
  }
  </script>
  
  <style scoped>
  .pdf-test {
    padding: 20px;
    text-align: center;
  }
  
  .upload-container {
    margin: 20px 0;
  }
  
  .preview {
    margin-top: 20px;
    display: flex;
    flex-direction: column;
    align-items: center;
  }
  
  .preview img {
    max-width: 100%;
    max-height: 500px;
    margin-bottom: 10px;
  }
  
  .back-link {
    display: inline-block;
    margin-top: 20px;
    padding: 10px 20px;
    background-color: #666;
    color: white;
    text-decoration: none;
    border-radius: 4px;
  }
  
  .back-link:hover {
    background-color: #555;
  }
  
  .size-buttons {
    margin: 20px 0;
    display: flex;
    justify-content: center;
    gap: 8px;
    flex-wrap: wrap;
    max-width: 800px;
    margin-left: auto;
    margin-right: auto;
  }
  
  .size-btn {
    padding: 6px 12px;
    border: 1px solid #ddd;
    border-radius: 4px;
    background-color: white;
    cursor: pointer;
    transition: all 0.3s;
    font-size: 14px;
  }
  
  .size-btn:hover {
    background-color: #f0f0f0;
  }
  
  .size-btn.active {
    background-color: #4CAF50;
    color: white;
    border-color: #4CAF50;
  }
  
  /* 为适应按钮添加特殊样式 */
  .size-btn:last-child {
    /* 使用与其他按钮相同的样式 */
    background-color: white;
    color: inherit;
    border-color: #ddd;
  }
  
  .size-btn:last-child:hover {
    background-color: #f0f0f0;
  }
  
  .size-btn:last-child.active {
    background-color: #4CAF50;
    color: white;
    border-color: #4CAF50;
  }
  
  .modal {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(0, 0, 0, 0.5);
    display: flex;
    justify-content: center;
    align-items: center;
    z-index: 1000;
  }
  
  .modal-content {
    background-color: white;
    padding: 20px;
    border-radius: 8px;
    max-width: 90%;
    max-height: 90vh; /* 使用视口高度单位 */
    overflow: auto;
  }
  
  .zoom-controls {
    display: flex;
    justify-content: center;
    gap: 10px;
    margin: 10px 0;
  }
  
  .zoom-btn {
    display: flex;
    align-items: center;
    padding: 6px 12px;
    border: 1px solid #ddd;
    border-radius: 4px;
    background-color: white;
    cursor: pointer;
    transition: all 0.3s;
    font-size: 14px;
    min-width: 80px; /* 确保按钮宽度一致 */
    justify-content: center; /* 居中按钮内容 */
  }
  
  .zoom-btn:hover {
    background-color: #f0f0f0;
  }
  
  .zoom-icon {
    font-weight: bold;
    margin-right: 4px;
    font-size: 16px;
  }
  
  .crop-container {
    max-width: 800px;
    max-height: 600px;
    margin: 10px auto;
    overflow: hidden;
    background-color: #f5f5f5;
  }
  
  .crop-container img {
    max-width: 100%;
  }
  
  .modal-buttons {
    margin-top: 20px;
  }
  
  .confirm-btn, .cancel-btn {
    padding: 8px 20px;
    margin: 0 10px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    transition: background-color 0.3s;
  }
  
  .confirm-btn {
    background-color: #4CAF50;
    color: white;
  }
  
  .confirm-btn:hover {
    background-color: #45a049;
  }
  
  .cancel-btn {
    background-color: #666;
    color: white;
  }
  
  .cancel-btn:hover {
    background-color: #555;
  }
  
  .crop-info {
    margin: 10px 0;
    color: #666;
    font-size: 14px;
    line-height: 1.8; /* 增加行间距 */
  }
  
  /* 为重置按钮添加特殊的 hover 效果 */
  .zoom-btn:last-child:hover {
    background-color: #f0f0f0;
    color: #666;
  }
  
  .download-buttons {
    margin-top: 15px;
    display: flex;
    justify-content: center;
    gap: 10px;
  }
  
  .download-btn {
    display: flex;
    align-items: center;
    padding: 8px 16px;
    border: 1px solid #4CAF50;
    border-radius: 4px;
    background-color: white;
    color: #4CAF50;
    cursor: pointer;
    transition: all 0.3s;
    font-size: 14px;
  }
  
  .download-btn:hover {
    background-color: #4CAF50;
    color: white;
  }
  
  .download-icon {
    font-weight: bold;
    margin-right: 6px;
    font-size: 16px;
  }
  
  .quality-control {
    margin-top: 10px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 5px;
  }
  
  .quality-control span {
    font-size: 14px;
    color: #666;
  }
  
  .quality-slider {
    width: 200px;
    height: 4px;
    -webkit-appearance: none;
    background: #ddd;
    outline: none;
    border-radius: 2px;
    cursor: pointer;
  }
  
  .quality-slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 16px;
    height: 16px;
    background: #4CAF50;
    border-radius: 50%;
    cursor: pointer;
    transition: background-color 0.3s;
  }
  
  .quality-slider::-moz-range-thumb {
    width: 16px;
    height: 16px;
    background: #4CAF50;
    border: none;
    border-radius: 50%;
    cursor: pointer;
    transition: background-color 0.3s;
  }
  
  .quality-slider::-webkit-slider-thumb:hover {
    background: #45a049;
  }
  
  .quality-slider::-moz-range-thumb:hover {
    background: #45a049;
  }
  
  /* 优化滑块轨道样式 */
  .quality-slider::-webkit-slider-runnable-track {
    height: 4px;
    background: #ddd;
    border-radius: 2px;
  }
  
  .quality-slider::-moz-range-track {
    height: 4px;
    background: #ddd;
    border-radius: 2px;
  }
  
  .page-selector {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    margin: 10px 0;
  }
  
  .page-selector select {
    padding: 6px 12px;
    border: 1px solid #ddd;
    border-radius: 4px;
    font-size: 14px;
    cursor: pointer;
    outline: none;
    background-color: white;
  }
  
  .page-selector select:hover {
    border-color: #4CAF50;
  }
  
  .page-selector select:focus {
    border-color: #4CAF50;
    box-shadow: 0 0 0 2px rgba(74, 175, 80, 0.2);
  }
  
  .total-pages {
    color: #666;
    font-size: 14px;
  }
  </style> 